package com.bjpowernode.handler;

import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.bjpowernode.constant.Constant;
import com.bjpowernode.entity.TUser;
import com.bjpowernode.result.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录成功后跳转到这个handler
 */
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    /*
    * 这里要注入上面的无泛型的，不要注入下面的RedisTemplate<String,Object>,
    * 因为如果注入这个带String泛型的，那么spring在自动装配时，就需要找到一个完全
    * 匹配RedisTemplate<String,Object>类型的bean，但springboot默认自动配置的
    * 是RedisTemplate原始类型，也就是上面的无泛型类型，也相当于RedisTemplate<Object,Object>
    * springboot的RedisAutoConfiguration默认创建的RedisTemplate只有两种，
    * 就是：RedisTemplate<Object,Object>和StringRedisTemplate(等价RedisTemplate<String,
    * String>)
    * 所以在没有手动装配RedisTemplate<String,Object>的情况下直接注入的话，会找不到
    * */
    @Autowired
    private RedisTemplate redisTemplate;
//    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        //生成jwt
        TUser user = (TUser)authentication.getPrincipal();
        String userJson = JSONUtil.toJsonStr(user);
        String token = JWTUtil.createToken(Map.of("user",userJson),
                Constant.SECRET.getBytes(StandardCharsets.UTF_8));
        //将jwt写入redis
//        redisTemplate.opsForValue().set("token:" + user.getId(),token);
        //设置了序列化方式为string后，在存储时要把id转为String，否则会报错
        redisTemplate.opsForHash().put(Constant.REDIS_TOKEN_KEY,user.getId().toString(),token);
        R result = R.ok("登录成功",token);
        String json = JSONUtil.toJsonStr(result);
        response.getWriter().write(json);
    }
}
